﻿using Abp.UI;
using Paas.Core.Sys.Entities;
using Paas.Core.Sys.Interfaces;
using Microsoft.EntityFrameworkCore;
using Basefr.Core;
using Basefr.Core.Extensions;
using Basefr.Runtime.Helpers;
using System;
using System.Linq;

namespace Paas.Core.Sys
{
    public class SysManager : CoreService, ISysManager
    {
        private readonly IMainRepository<User, long> _userRepo;
        private readonly IMainRepository<Role> _roleRepo;
        private readonly IMainRepository<Organization> _organizationRepo;

        public SysManager(IMainRepository<User, long> userRepo, IMainRepository<Role> roleRepo, IMainRepository<Organization> organizationRepo)
        {
            _userRepo = userRepo;
            _roleRepo = roleRepo;
            _organizationRepo = organizationRepo;
        }

        public User SaveUser(User user)
        {
            user.UserName = user.UserName.Trim();
            user.Name = user.Name?.Trim();
            user.Phone = user.Phone?.Trim();
            user.Email = user.Email?.Trim();
            user.EmployeeNo = user.EmployeeNo?.Trim();
            user.OfficePhone = user.OfficePhone?.Trim();

            if (_userRepo.GetAll().Any(p => p.UserName == user.UserName && p.Id != user.Id))
            {
                throw new UserFriendlyException("登录名冲突，已存在相同的登录名");
            }

            if (user.Id <= 0)
            {
                user.PasswordSalt = Guid.NewGuid().ToString("N");
                user.Password = HashHelper.Hash(user.UserName, user.PasswordSalt);

                return _userRepo.Insert(user);
            }

            var exist = _userRepo.GetAll().Include(p => p.Organization).First(user.Id);

            exist.Name = user.Name;
            exist.Phone = user.Phone;
            exist.Email = user.Email;
            exist.EmployeeNo = user.EmployeeNo;
            exist.OfficePhone = user.OfficePhone;
            exist.OrganizationId = user.OrganizationId;
            exist.IsLeader = user.IsLeader;
            exist.IsActive = user.IsActive;

            return exist;
        }

        public Role SaveRole(Role role)
        {
            var conflict = _roleRepo.FirstOrDefault(r => r.Name == role.Name && r.Id != role.Id);
            if (conflict != null)
            {
                throw new UserFriendlyException("角色名称冲突，已存在同名角色");
            }

            if (role.Id <= 0)
            {
                _roleRepo.InsertAndGetId(role);

                return role;
            }

            var exist = _roleRepo.Get(role.Id);

            if (exist.IsPreDefined)
            {
                throw new UserFriendlyException("不能修改系统与定义角色");
            }

            exist.Name = role.Name;
            exist.IsActive = role.IsActive;

            return exist;
        }

        public Organization SaveOrganization(Organization organization)
        {
            organization.Name = organization.Name.Trim();

            if (_organizationRepo.GetAll().Any(e => e.Id != organization.Id && e.Name == organization.Name))
            {
                throw new UserFriendlyException("部门名称冲突，已存在同名部门");
            }

            if (organization.Id <= 0)
            {
                if (organization.ParentId.HasValue)
                {
                    var parent = _organizationRepo.Get(organization.ParentId.Value);

                    if (parent.Level >= 5)
                    {
                        throw new UserFriendlyException("最多只能建立六级组织部门");
                    }

                    organization.Parent = parent;
                    organization.Level = parent.Level + 1;
                }

                _organizationRepo.InsertAndGetId(organization);

                return organization;
            }
            else
            {
                var exist = _organizationRepo.Get(organization.Id);

                if (exist.IsPreDefined)
                {
                    throw new UserFriendlyException("不能修改系统预定义部门");
                }

                exist.Name = organization.Name;

                CurrentUnitOfWork.SaveChanges();

                return exist;
            }
        }
    }
}

